import configureStore from 'stores';
import CryptoJS from 'crypto-js';

const AES = CryptoJS.AES;

// 邮箱脱敏
const sensitiveEmail = email => {
  if (!email) return email;
  let emailAry = email.split('@'),
    emailTitle = emailAry[0];
  if (emailTitle) {
    let emailLen = emailTitle.length,
      emailLenHalf = Math.floor(emailLen / 2),
      emailLenStart = Math.floor((emailLen - emailLenHalf) / 2),
      emailLenEnd = emailLenStart + emailLenHalf,
      newEmailAry = [],
      pos = 0;
    while (pos < emailLen) {
      if (pos < emailLenStart) {
        newEmailAry.push(emailTitle[pos]);
      } else if (pos < emailLenEnd) {
        newEmailAry.push('*');
      } else {
        newEmailAry.push(emailTitle[pos]);
      }
      pos++;
    }
    emailAry[0] = newEmailAry.join('');
    return emailAry.join('@');
  }
  return email;
};

// 姓名脱敏
const sensitiveName = name => {
  let nameReg = /^(.).(.*)$/img;
  return name.replace(nameReg, '$1*$2');
};

// 手机号脱敏
const sensitiveMobile = (mobile) => {
  let mobileReg = /^(.{3}).{4}(.*)$/img;
  return mobile.replace(mobileReg, '$1****$2');
};

// 处理错误信息
const getErrorMessage = (error) => {
  if (!error) return '';
  let errorMessage = '';
  let errorData = (error || {}).data || {};
  // 处理 errorData 为非对象的情况
  if (typeof errorData != 'object') {
    let _errorData = errorData;
    errorData = {
      message: _errorData
    };
  }

  let {message, validationErrors, failReason} = errorData;
  let validationError = '';
  errorMessage = message || '';
  // 处理validationErrors
  if (validationErrors && (validationError = validationErrors[0])) {
    errorMessage += ':' + (validationError || {}).message;
  }
  // 处理failReasons
  if (failReason) {
    let failReasonAry = [];
    for (let key in failReason) {
      failReasonAry.push(`${key}:${failReason[key]}`);
    }
    errorMessage += ':' + failReasonAry.join(',');
  }
  errorData.message = errorMessage;
  return errorMessage;
};

const WHITE_LIST_URL_MAP = new Map([
  ['/api/approvals/reject', {
    apiModule: 'approval',
    moduleName: '审批',
    moduleAction: '驳回错误'
  }],
  ['/api/approvals/pass', {
    apiModule: 'approval',
    moduleName: '审批',
    moduleAction: '通过错误'
  }],
  ['/api/approvals/reject/expensereport/invoice', {
    apiModule: 'approval',
    moduleName: '审批',
    moduleAction: '费用驳回错误'
  }],
  ['/api/travel/applications/submit', {
    apiModule: 'application',
    moduleName: '申请单',
    moduleAction: '提交错误'
  }],
  ['/api/travel/applications/submit/v2', {
    apiModule: 'application',
    moduleName: '申请单',
    moduleAction: '提交错误'
  }],
  ['/api/loanBill/submit/v2', {
    apiModule: 'loanBill',
    moduleName: '借款单',
    moduleAction: '提交错误'
  }],
  ['/api/v3/expense/report/submit', {
    apiModule: 'expenseClaim',
    moduleName: '报销单',
    moduleAction: '提交错误'
  }],
  ['/api/expense/reports/custom/form/draft', {
    apiModule: 'expenseClaim',
    moduleName: '报销单',
    moduleAction: '保存错误'
  }],
  ['/invoice/api/v4/invoices', {
    apiModule: 'expenseList',
    moduleName: '费用',
    moduleAction: '保存错误'
  }],
]);

let currentUserOID = '',
  hasIniited = false;
const hostname = window.location.hostname,
  isStageEnv = hostname === 'stage.huilianyi.com',
  isProdEnv = /^console.*\.huilianyi\.com$/.test(hostname),
  urlParseReg = /[^\/](\/[^\/][^\?]+)/,
  iterationVersion = '09-10-11'; // 迭代版本号，用来做归档



const init = () => {
  const dsnMap = {
    'dev': 'http://3830c347eea3415d9864199485fe160a@192.168.10.150:9000/4',
    'stage': 'https://388259d2b02548e3998a95d2b449c8ca@sentry-inspect.huilianyi.com/4',
    'prod':  'https://49472da74c284e1f8c5471f95f01d988@sentry-inspect.huilianyi.com/3'
  };
  let env = isProdEnv ? 'prod' : isStageEnv ? 'stage' : 'dev';
  const intergrationOptions = {
    beacon: false,
    console: false,
    dom: false,
    fetch: false,
    sentry: false,
    history: false,
    xhr: false
  };
  if (isProdEnv) {
    Object.assign(intergrationOptions, {
      history: true,
      xhr: true
    });
    Sentry.init({
      dsn: dsnMap[env],
      defaultIntegrations: false,
      integrations: [new Sentry.Integrations.Breadcrumbs(intergrationOptions)]
    });
  } else if (isStageEnv) {
    Object.assign(intergrationOptions, {
      beacon: true,
      console: true,
      dom: true,
      history: true,
      xhr: true
    });
    Sentry.init({
      dsn: dsnMap[env],
      defaultIntegrations: false,
      integrations: [new Sentry.Integrations.Breadcrumbs(intergrationOptions)]
    });
  } else {
    Sentry.init({
      dsn: dsnMap[env]
    });
  }
  hasIniited = true;
};

if (window.Sentry) {
  if (isStageEnv || isProdEnv) {
    init();
  }
}
const ravenHttpError = (url, error) => {
  // 如果不是正式环境或stage环境就不进行收集
  if (!isStageEnv && !isProdEnv) return;
  if (!hasIniited) {
    if (!window.Sentry)return
    init();
  }
  // 删掉error中冗余的东西
  delete error.request;
  if(url.startsWith('http')){
    url = url.match(urlParseReg)[1];
  }

  let store = configureStore.store.getState();
  let user = store.login.user;
  let tenant = store.login.tenant;
  let userOID = user && user.userOID;
  let errorData = error.data;
  let exceptionCategory = errorData && errorData.exceptionCategory || 'OTHER';
  let tags = {};
  // 搜集用户信息
  if (userOID && currentUserOID != userOID) {
    currentUserOID = userOID;
    let {fullName, mobile, email, avatar, isVIP = false} = user;
    let {tenantName} = tenant;
    Sentry.setUser({
      username: sensitiveName(fullName),
      email: sensitiveMobile(email),
      avatar: avatar,
      data: {
        encrypted: true,
        userOID: userOID,
        tenantName: tenantName,
        mobile: sensitiveMobile(mobile),
        encryptedMobile: AES.encrypt(mobile, userOID).toString(),
        encryptedUsername: AES.encrypt(fullName, userOID).toString(),
        encryptedEmail: AES.encrypt(email, userOID).toString()
      }
    });
    tags = Object.assign(tags, {
      iterationVersion: iterationVersion,
      isVIP: isVIP,
      tenantName: tenantName,
      exceptionCategory: exceptionCategory,
    });
  }
  let fingerprint = url + ',' + iterationVersion + ',' + exceptionCategory,
    transaction = '',
    localError = new Error(getErrorMessage(error));
  Object.assign(localError, error);
  // 搜集报错
  if (Sentry.captureException) {
    if (WHITE_LIST_URL_MAP.has(url)) {
      let urlMap = WHITE_LIST_URL_MAP.get(url),
        {apiModule, moduleName, moduleAction} = urlMap;
      Sentry.setTags({...tags, ...urlMap});
      transaction = [iterationVersion, moduleName, moduleAction, exceptionCategory].join('-');
      Sentry.withScope((scope) => {
        scope.setTransaction(transaction);
        scope.setFingerprint(fingerprint);
        scope.setExtras(error);
        Sentry.captureException(localError);
      });
    } else {
      transaction = [iterationVersion, url].join('-');
      // 正式环境只监听列表中的接口，其它接口只在非正式环境才监听
      if (!isProdEnv) {
        Sentry.withScope((scope) => {
          scope.setTransaction(transaction);
          scope.setFingerprint(fingerprint);
          scope.setExtras(error);
          Sentry.captureException(localError);
        });
      }
    }

  }
};
export default ravenHttpError;
